package com.xhwl.centiotdata.controller;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xhwl.centiotdata.handler.account.AccountFactory;
import com.xhwl.centiotdata.handler.account.AccountHandler;
import com.xhwl.centiotdata.pollingtrigger.vehicle.VehicleDispatcher;
import com.xhwl.centiotdata.service.cent.IAccountCentService;
import com.xhwl.centiotdata.service.cent.IDeviceCentService;
import com.xhwl.common.dto.cent.sdata.AccountDTO;
import com.xhwl.common.enums.CategoryEnum;
import com.xhwl.common.pojo.ResultBuilder;
import com.xhwl.common.pojo.ResultJson;
import com.xhwl.common.pojo.cent.device.DeviceProjSupplierCategory;
import com.xhwl.common.pojo.cent.sdata.personnel.StaffDTO;
import com.xhwl.common.query.cent.device.ProductAccessQuery;
import com.xhwl.common.query.cent.sdata.StaffQuery;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


/**
 * 暴露一些同步用的接口
 */
@RestController
@Slf4j
public class SyncController {

    @Autowired
    private IAccountCentService accountCentService;

    @Resource
    private IDeviceCentService iDeviceCentService;

    @Autowired
    private VehicleDispatcher vehicleDispatcher;

    private static final ExecutorService executor = Executors.newCachedThreadPool();

    /**
     * 同步星启某个组织下账号到第三方
     *
     * @param enterpriseId 企业id
     * @param orgId        组织id
     * @param updateFlag   是否全部更新 false 删除AuthAccountMapping和第三方数据后新增  true 仅同步AuthAccountMapping中不存在的人员
     * @param projectId    项目id
     * @param industryId   业态id
     * @param showCurrent  是否只同步当前组织（否则子组织也同步）
     * @return
     */
    @PostMapping("/sync/syncAccountToDaHuaIcc")
    public ResultJson syncAccountToDaHuaIcc(@RequestParam("enterpriseId") Integer enterpriseId,
                                            @RequestParam("orgId") Integer orgId,
                                            @RequestParam("updateFlag") Boolean updateFlag,
                                            @RequestParam("projectId") Integer projectId,
                                            @RequestParam("industryId") Integer industryId,
                                            @RequestParam("showCurrent") Boolean showCurrent) {
        syncAccountOrg(enterpriseId, orgId, updateFlag, projectId, industryId, showCurrent);
        return ResultBuilder.success();
    }

    @PostMapping("/sync/syncFuShi")
    public ResultJson syncAccountToFushi() {
        vehicleDispatcher.executePullAccessRecord();
        return ResultBuilder.success();
    }


    /**
     * 同步组织下账号数据
     */
    public void syncAccountOrg(Integer enterpriseId, Integer orgId, Boolean updateFlag, Integer projectId, Integer industryId, Boolean showCurrent) {
        log.info("==同步组织下账号数据到第三方开始==");
        StaffQuery staffQuery = new StaffQuery();
        staffQuery.setEnterpriseId(enterpriseId);
        staffQuery.setShowCurrent(showCurrent);
        if (orgId != null) {
            staffQuery.setOrgId(orgId);
        }

        executor.submit((Callable<String>) () -> {
            List<DeviceProjSupplierCategory> deviceProjSupplierCategories = iDeviceCentService.listProductAccess((short) 1, new ProductAccessQuery(projectId, CategoryEnum.DOOR.getId()));
            if (CollectionUtils.isNotEmpty(deviceProjSupplierCategories)) {
                //放线程，防止超时
                Page page = new Page();
                page.setCurrent(1);
                page.setSize(500);//每次500
                Page<StaffDTO> staffDTOPage = accountCentService.pageV2(staffQuery, page);
                List<StaffDTO> staffDTOS = staffDTOPage.getRecords();
                log.error("获取组织下的人数：{}", staffDTOPage.getTotal());
                if (!staffDTOS.isEmpty()) {
                    syncStaffDto(staffDTOS, updateFlag, projectId, industryId, deviceProjSupplierCategories);
                    long pages = staffDTOPage.getPages();
                    if (pages > 1) {
                        for (int i = 2; i <= pages; i++) {
                            page.setCurrent(i);
                            Page<StaffDTO> staffDTOPage1 = accountCentService.pageV2(staffQuery, page);
                            List<StaffDTO> staffDTOS1 = staffDTOPage1.getRecords();
                            syncStaffDto(staffDTOS1, updateFlag, projectId, industryId, deviceProjSupplierCategories);
                        }
                    }
                }
            }
            log.info("==同步组织下账号数据到第三方结束==");
            return null;
        });

    }

    public void syncStaffDto(List<StaffDTO> staffDTOS, Boolean updateFlag, Integer projectId, Integer industryId, List<DeviceProjSupplierCategory> deviceProjSupplierCategories) {
        for (StaffDTO staffDTO : staffDTOS) {
            if (updateFlag) {
                deviceProjSupplierCategories.forEach(config -> {
                    AccountHandler invokeStrategy = AccountFactory.getInvokeStrategy(config.getProductId());
                    staffDTO.setIndustryId(industryId.shortValue());
                    invokeStrategy.update(staffDTO, projectId, config);
                });
            } else {
                deviceProjSupplierCategories.forEach(config -> {
                    AccountHandler invokeStrategy = AccountFactory.getInvokeStrategy(config.getProductId());
                    staffDTO.setIndustryId(industryId.shortValue());
                    AccountDTO accountDTO = new AccountDTO();
                    accountDTO.setId(staffDTO.getAccountId());
                    invokeStrategy.delete(accountDTO, projectId, config);
                    invokeStrategy.add(staffDTO, projectId, config);
                });
            }
        }
    }

}
